home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
cgazv5n4.arc
/
VIDPRIM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-23
|
12KB
|
418 lines
/****************************************************************
* File: VIDPRIM.C
* Date: Feb. 1991
* Function: Primitive video operations
* Authors: Craig Miller, George Spofford
* Compilers: MSC 6.0, Turbo C++ 1.0, MetaWare HighC-386 1.7
* Switches:
* MSC 6.0: Assumes large memory model
* cl -AL -Ox -c vidprim.c
* High C:
* hc386 -c -DDOS_386 vidprim.c
*
* Object code may be freely used. Source code may be used freely
* if authorship/publication is acknowledged
****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <dos.h> /* for int86(), FP_OFF and FP_SEG macros */
#define VIDPRIM_SRC
#include "vidprim.h"
#define N_COLS 80 /* fixed # of columns in std, CGA/EGA/VGA */
#define _TEXTMONO 7 /* code for monochrome text mode */
#if ! defined (DOS_386) /* assuming large-model 8086 compile */
#define _FAR far
#define FFMEMCPY memcpy
#define FF_R_MEMCPY memmove
#else /* assuming MetaWare High C-386 v. 1.7 */
#define _FAR _far
#define SS_SEG 0x1C /* Phar Lap's screen segment selector */
#define max( a, b) ((a) > (b) ? (a) : (b))
/* use MetaWare's _movedata function for forward copy */
#define FFMEMCPY( t, f, n) \
_movedata (FP_SEG(f), FP_OFF(f), FP_SEG(t), FP_OFF(t), n)
/* quick define of reverse copy function */
void FF_R_MEMCPY (void _FAR *t, void _FAR *f, int n)
{
register char _FAR *tp;
register char _FAR *fp;
register int loop = n;
for (tp = ((char _FAR *) t) + loop,
fp = ((char _FAR *) f) + loop;
--loop >= 0;
*--tp = *--fp)
;
}
#endif
/* ptr to display memory */
static short _FAR *dispmem = (short _FAR *) NULL;
/* current display attribute */
static color_t curattrib = 0x07;
/* current display window */
static bbox_t curbox = {{0,0},{25,80}};
/* Display state: */
static struct {
int mode; /* mode */
int cols; /* # of text columns on screen */
int rows; /* # of text rows on screen */
} CurDispState;
/* VideoBios1: Makes EGA or VGA video bios call. Used for BIOS
** calls that use registers AL - BH as input, and return AL==0x12
** if successful (See BIOS #defines in VIDPRIM.H)
*/
int VideoBios1 (unsigned char al, unsigned char ah,
unsigned char bl, unsigned char bh)
{
union REGS inregs, outregs;
inregs.h.al = al;
inregs.h.ah = ah;
inregs.h.bl = bl;
inregs.h.bh = bh;
int86 ( 0x10, &inregs, &outregs);
return ( outregs.h.al == 0x12 );
}
/* VideoBios2: Makes EGA or VGA video bios call. Used for BIOS
** calls that use registers AL - BL as input and BH as output.
** Returns register BH. (See BIOS #defines in VIDPRIM.H)
*/
unsigned char VideoBios2 (unsigned char al, unsigned char ah,
unsigned char bl)
{
union REGS inregs, outregs;
inregs.h.al = al;
inregs.h.ah = ah;
inregs.h.bl = bl;
int86 ( 0x10, &inregs, &outregs);
return ( outregs.h.bh );
}
/* InitDisplay: Sets the text display to the given mode (3 or 7)
** and the number of text lines given.
*/
void _PASCAL InitDisplay (int mode, int rows)
{
EGA_setvideomode (mode); /* set the mode (either 3 or 7) */
CurDispState.mode = mode;
CurDispState.cols = N_COLS;
switch (rows) {
case 50:
VGA_400lines();
CurDispState.rows = 50;
EGA_SetFont (FONT8X8NORESET);
break;
case 43:
CurDispState.rows = 43;
EGA_SetFont (FONT8X8NORESET);
break;
case 25:
default:
VGA_400lines();
EGA_SetFont (FONT8X16NORESET);
CurDispState.rows = 25;
}
#if ! defined (DOS_386)
dispmem = (short _FAR *)
((CurDispState.mode == _TEXTMONO) ? 0xB0000000 : 0xB8000000);
#else
{ /* 48-bit far ptr creation */
struct _farptrovly {int off; short seg;};
((struct _farptrovly *) &dispmem)->seg =
SS_SEG; /* Phar Lap screen seg */
((struct _farptrovly *) &dispmem)->off = 0x00000000;
}
#endif
curbox.o[DOWN] = 0;
curbox.o[ACROSS] = 0;
curbox.n[DOWN] = CurDispState.rows;
curbox.n[ACROSS] = CurDispState.cols;
curattrib = 0x07;
}
/* SetCurAttrib: Sets the current display attribute.
** Returns the previous current-attribute value.
*/
color_t SetCurAttrib (color_t attr)
{
color_t ret;
ret = curattrib;
curattrib = attr;
return (ret);
}
/* SetCurBox
** Sets the current screen display window
*/
void SetCurBox (bbox_t *bbp)
{
memcpy (&curbox, bbp, sizeof (bbox_t));
}
/* SetTextCursor: Sets current cursor position to
** R,C (coordinate system starts at 0, 0)
*/
void _PASCAL SetTextCursor (int r, int c)
{
union REGS regs;
regs.h.ah = 0x02; /* func. is set cursor position */
regs.h.bh = 0;
regs.h.dh = (char) r;
regs.h.dl = (char) c;
int86 (0x10, ®s, ®s); /* set cursor at row, col */
}
/* ScrollBox: Scrolls the given region down by ND rows and
** right by NA columns
*/
void _PASCAL ScrollBox (bbox_t *bbp, int nd, int na)
{
short _FAR *tptr; /* primary display memory ptr */
short _FAR *fptr; /* secondary display ptr */
register int loop; /* primary loop index */
register int loop2; /* secondary loop index */
short _FAR *boxptr; /* ptr to UL corner of scroll-box */
short attr; /* background filler */
int nbytes; /* # of bytes to transfer per move */
/* calculate region reference ptr */
boxptr = dispmem + bbp->o[DOWN] * CurDispState.cols
+ bbp->o[ACROSS];
/* make newly-blank-space representation */
attr = ((short) (curattrib << 8)) + ' ';
/*------------------- VERTICAL ------------------------*/
if (nd != 0) { /* if scrolling vertically */
nbytes = bbp->n[ACROSS] * /* scroll the entire */
sizeof(short); /* width of the box. */
if (nd < 0) {
/*----------------------- SCROLL UP -------------------*/
nd = -nd;
if (nd > bbp->n[DOWN]) /* clip # to scroll to box size */
nd = bbp->n[DOWN];
/* copy rows, advancing downwards */
for (tptr = boxptr, fptr =
boxptr + nd * CurDispState.cols,
loop = bbp->n[DOWN] - nd;
--loop >= 0;
tptr += CurDispState.cols, fptr += CurDispState.cols)
FFMEMCPY (tptr, fptr, nbytes);
/* blank each remaining row with current attribute
* tptr is set to first row after scrolled region. */
for (loop2 = nd, fptr = tptr; --loop2 >= 0;
fptr += CurDispState.cols)
for (tptr = fptr, loop = bbp->n[ACROSS];
--loop >= 0; *tptr++ = attr)
;
}
else {
/*------------------- SCROLL DOWN ---------------------*/
if (nd > bbp->n[DOWN]) /* clip to region */
nd = bbp->n[DOWN];
/* copy rows, advancing upwards */
for (tptr = boxptr + (bbp->n[DOWN]-1) * CurDispState.cols,
fptr = boxptr + (bbp->n[DOWN]-1-nd) * CurDispState.cols,
loop = bbp->n[DOWN] - nd;
--loop >= 0;
tptr -= CurDispState.cols, fptr -= CurDispState.cols)
FFMEMCPY (tptr, fptr, nbytes);
/* blank each remaining rows with current attribute
* tptr is set to first row above scrolled region. */
for (loop2 = nd, fptr = tptr; --loop2 >= 0;
fptr -= CurDispState.cols)
for (tptr = fptr, loop = bbp->n[ACROSS];
--loop >= 0; *tptr++ = attr)
;
}
} /* vertical scroll */
/*--------------- HORIZONTAL ------------------------*/
if (na != 0) { /* if any horizontal scroll */
if (na > 0) {
/*----------------- SCROLL RIGHT ----------------------*/
/* scroll only NA chars */
nbytes = (bbp->n[ACROSS] - na) * sizeof (short);
if (na > bbp->n[ACROSS]) /* clip to size of box */
na = bbp->n[ACROSS];
/* in each row, slide columns to
screen right (-> high memory) */
for (fptr = boxptr, tptr = boxptr + na,
loop = bbp->n[DOWN];
--loop >= 0;
fptr += CurDispState.cols, tptr += CurDispState.cols)
/* copy from high- to low-mem */
FF_R_MEMCPY (tptr, fptr, nbytes);
/* in each row, blank unmoved columns */
for (loop2 = bbp->n[DOWN], fptr = boxptr; --loop2 >= 0;
fptr += CurDispState.cols)
for (tptr = fptr, loop = na; --loop >= 0; *tptr++ = attr)
;
}
else {
/*----------------- SCROLL LEFT -----------------------*/
na = -na; /* take positive quantity */
nbytes = (bbp->n[ACROSS] - na) * sizeof (short);
if (na > bbp->n[ACROSS]) /* clip to box */
na = bbp->n[ACROSS];
/* in each row, move columns to
screen left (-> low memory) */
for (tptr = boxptr, fptr = boxptr + na,
loop = bbp->n[DOWN];
--loop >= 0;
tptr += CurDispState.cols, fptr += CurDispState.cols)
FFMEMCPY (tptr, fptr, nbytes);
/* blank out unmoved columns */
for (loop2 = bbp->n[DOWN], fptr =
boxptr + bbp->n[ACROSS] - na;
--loop2 >= 0;
fptr += CurDispState.cols)
for (loop = na, tptr = fptr; --loop >= 0;
*tptr++ = attr)
;
}
} /* horizontal scroll */
}
/* ClearBox: Clears out region represented in bounding box
** to current attribute.
*/
void ClearBox (bbox_t *bbp)
{
ScrollBox (bbp, bbp->n[DOWN], 0);
}
/* ClearScreen
** Clears screen to currently set attribute.
*/
void ClearScreen (void)
{
bbox_t bbox;
BBSET( bbox, 0, 0, CurDispState.rows, CurDispState.cols);
ClearBox (&bbox);
}
/* CursorOff
** Turns text cursor off.
*/
void CursorOff (void)
{
SetTextCursor (CurDispState.rows + 1, 0);
}
/* x_outch: Places a character on the screen, at R,C
** using the current text-rendering attributes.
** Returns # of chars put of screen (1 or 0)
*/
int _PASCAL x_outch (int r, int c, char ch)
{
register short _FAR *locdispmem;
/* clip to current box */
if ( ((unsigned) r) >= ((unsigned) curbox.n[DOWN])
|| ((unsigned) c) >= ((unsigned) curbox.n[ACROSS]) )
return (0);
locdispmem = dispmem + ((curbox.o[DOWN] + r) *
CurDispState.cols + curbox.o[ACROSS] + c);
*locdispmem = (short) (curattrib << 8) + (unsigned char) ch;
return (1);
}
/* x_outtext: Places a character string on the screen
** starting at R,C, using the current text-rendering attributes
*/
int _PASCAL x_outtext (int r, int c, char *str)
{
register short _FAR *locdispmem;
register char *cp;
int n, total;
short attrmask;
/* clip to box */
/* if out of curbox */
if ( ((unsigned) r) >= ((unsigned) curbox.n[DOWN])
|| ((unsigned) c) >= ((unsigned) curbox.n[ACROSS]) )
return (0);
locdispmem = dispmem + (curbox.o[DOWN] + r) *
CurDispState.cols + curbox.o[ACROSS] + c;
attrmask = curattrib << 8;
for (cp = str, n = max (0, curbox.n[ACROSS] - c), total = 0;
*cp && --n >= 0;
++total)
*locdispmem++ = attrmask | * (unsigned char *) cp++;
return (total);
}
/* xput_string
** Acts as a screen-printf() with row, column addressing
*/
int _CDECL xput_string (int r, int c, char *fmt,...)
{
static char buf[256];
va_list argptr;
/* if out of curbox, don't write */
if ( ((unsigned) r) >= ((unsigned) curbox.n[DOWN])
|| ((unsigned) c) >= ((unsigned) curbox.n[ACROSS]) )
return (0);
va_start (argptr, fmt); /* format arguments */
vsprintf (buf, fmt, argptr);
va_end (argptr);
return (x_outtext (r, c, buf));
}
/* END OF VIDPRIM.C */